package com.zheng.shop.admin.controller.product;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baidu.unbiz.fluentvalidator.ComplexResult;
import com.baidu.unbiz.fluentvalidator.FluentValidator;
import com.baidu.unbiz.fluentvalidator.ResultCollectors;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zheng.common.base.BaseController;
import com.zheng.common.base.BaseResult;
import com.zheng.common.validator.DecimalValidator;
import com.zheng.common.validator.LengthValidator;
import com.zheng.common.validator.NotNullValidator;
import com.zheng.common.validator.SizeValidator;
import com.zheng.shop.common.Enum.ParamType;
import com.zheng.shop.common.Enum.ProductStatusType;
import com.zheng.shop.common.constant.ShopResult;
import com.zheng.shop.common.constant.ShopResultConstant;
import com.zheng.shop.common.exception.ShopException;
import com.zheng.shop.dao.model.*;
import com.zheng.shop.rpc.api.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: xinqi
 * Date: 2017/11/27
 * Time: 14:27
 */
@Controller
@Api(value = "商品管理", description = "商品管理")
@RequestMapping("/manage/product/product")
public class ProductController extends BaseController {
    @Autowired
    private ShopProductService productService;
    @Autowired
    private ShopCategoryService productCategoryService;
    @Autowired
    private ShopAttributeKeyService keyService;
    @Autowired
    private ShopParamService paramService;
    @Autowired
    private ShopSkuService skuservice;
    @Autowired
    private ShopProductParamService productParamService;
    @Autowired
    private ShopProductAttributeService productAttributeService;
    @Autowired
    private ShopAttributeKeyService attributeKeyService;
    @Autowired
    private ShopSkuAttributeService skuAttributeService;
    private final static Logger _log = LoggerFactory.getLogger(ProductController.class);

    @ApiOperation(value = "商品首页")
    @RequiresPermissions("product:product:read")
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model) {
        JSONObject types = ProductStatusType.getJsonArray();
        model.addAttribute("types", types);
        return "/manage/product/product/index.jsp";
    }

    @ApiOperation(value = "商品列表")
    @RequiresPermissions("product:product:read")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Object list(@RequestParam(required = false, defaultValue = "0", value = "offset") int offset,
                       @RequestParam(required = false, defaultValue = "10", value = "limit") int limit,
                       @RequestParam(required = false, value = "search") String search,
                       @RequestParam(required = false, value = "sort") String sort,
                       @RequestParam(required = false, value = "order") String order,
                       @RequestParam(required = false, value = "id") Integer categoryId) {
        List<Map<String, Object>> rows = productService.selectProductMapList(search, sort, order, offset, limit, categoryId);
        int total = productService.selectProductCount(search, sort, order, offset, limit, categoryId);
        Map<String, Object> result = new HashMap<>();
        result.put("rows", rows);
        result.put("total", total);
        return result;
    }

    @ApiOperation(value = "新增商品")
    @RequiresPermissions("product:product:create")
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public String create(Model model, Integer categoryId) {
        List<ShopProduct> productList = productService.selectList(null);
        model.addAttribute("productList", productList);
        if (null != categoryId) {
            ShopCategory productCategory = productCategoryService.selectById(categoryId);
            model.addAttribute("productCategory", productCategory);
        }
        JSONObject paramTypes = ParamType.getJsonArray();
        model.addAttribute("paramTypes", paramTypes);
        return "/manage/product/product/create.jsp";
    }

    @ApiOperation(value = "获取分类属性")
    @RequiresPermissions("product:product:create")
    @RequestMapping(value = "/getAttributeAndParam", method = RequestMethod.GET)
    @ResponseBody
    public Object getAttributeAndParam(Model model, @RequestParam(value = "productCategoryId", required = true) Integer productCategoryId) {
        JSONArray attributeList = keyService.getKeyValueJson(productCategoryId);
        List<ShopParam> paramList = paramService.getParamByProductCategoryId(productCategoryId);
        JSONObject json = new JSONObject();
        json.put("attributeList", attributeList);
        json.put("paramList", paramList);
        return new ShopResult(ShopResultConstant.SUCCESS, json);
    }

    @ApiOperation(value = "新增商品")
    @RequiresPermissions("product:product:create")
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public Object create(@RequestBody JSONObject param) {
        /**
         * param :
         * product 商品基本信息
         * skus sku数组，商品所包含的sku基本信息
         * hasAttribute boolean 是否包含属性
         * attributes 属性数组
         */
        JSONObject productJson = param.getJSONObject("product");
        ShopProduct product = productJson.toJavaObject(ShopProduct.class);
        JSONArray skusArray = param.getJSONArray("skus");
        List<ShopSku> skuList = skusArray.toJavaList(ShopSku.class);
        ComplexResult result = doValidator(product, skuList);
        if (!result.isSuccess()) {
            return new ShopResult(ShopResultConstant.FAILED, result.getErrors().get(0).getErrorMsg());
        }
        try {
            productService.createProduct(param);
        } catch (ShopException e) {
            return new ShopResult(ShopResultConstant.FAILED, e.getMessage());
        }
        return new ShopResult(ShopResultConstant.SUCCESS, ShopResultConstant.SUCCESS);
    }

    //验证商品所有信息
    private ComplexResult doValidator(ShopProduct product, List<ShopSku> skuList) {
        ComplexResult result = FluentValidator.checkAll()
                .on(product.getName(), new LengthValidator(1, 20, "商品名称"))
                .on(product.getBrandId(), new NotNullValidator("商品品牌"))
                .on(product.getProductCategoryId(), new NotNullValidator("商品分类"))
                .on(product.getMarketable(), new NotNullValidator("是否上架"))
                .doValidate()
                .result(ResultCollectors.toComplex());
        if (!result.isSuccess()) {
            return result;
        }

        for (ShopSku sku : skuList) {
            result = FluentValidator.checkAll()
                    .on(sku.getPrice(), new DecimalValidator(0, 15, "sku价格"))
                    .on(sku.getCostPrice(), new DecimalValidator(0, 15, "sku成本价"))
                    .on(sku.getMarketPrice(), new DecimalValidator(0, 15, "sku市场价"))
                    .on(sku.getInventory(), new SizeValidator(0, 999999999, "sku库存"))
                    .on(sku.getName(), new LengthValidator(1, 20, "sku名称"))
                    .doValidate()
                    .result(ResultCollectors.toComplex());
            if (!result.isSuccess()) {
                return result;
            }
        }
        return result;
    }

    @ApiOperation(value = "编辑商品")
    @RequiresPermissions("product:product:update")
    @RequestMapping(value = "/update/{id}", method = RequestMethod.GET)
    public String update(@PathVariable("id") Integer id, Model model) {
        //获取商品信息
        Map<String, Object> productMap = productService.selectProduct(id);
        JSONObject product = JSON.parseObject(JSON.toJSONString(productMap));
        List<String> imageList = product.getJSONArray("image_path").toJavaList(String.class);
        //获取商品参数信息
        EntityWrapper<ShopProductParam> productParamEntityWrapper = new EntityWrapper<>();
        productParamEntityWrapper.where("product_id=" + product.getInteger("id"));
        List<ShopProductParam> productParamList = productParamService.selectList(productParamEntityWrapper);
        //获取参数信息
        EntityWrapper<ShopParam> paramEntityWrapper = new EntityWrapper<>();
        paramEntityWrapper.where("category_id=" + product.getInteger("product_category_id"));
        List<ShopParam> paramList = paramService.selectList(paramEntityWrapper);
        //获取规格信息
        EntityWrapper<ShopAttributeKey> attributeKeyEntityWrapper = new EntityWrapper<>();
        attributeKeyEntityWrapper.where("category_id=" + product.getInteger("product_category_id"));
        List<ShopAttributeKey> attributeKeyList = attributeKeyService.selectList(attributeKeyEntityWrapper);
        //获取商品规格信息
        EntityWrapper<ShopProductAttribute> productAttributeEntityWrapper = new EntityWrapper<>();
        productAttributeEntityWrapper.where("product_id=" + product.getInteger("id"));
        List<ShopProductAttribute> productAttributeList = productAttributeService.selectList(productAttributeEntityWrapper);
        //获取sku信息
        List<Map<String, Object>> skuMapList = skuservice.selectSkuMapList(product.getInteger("id"), ProductStatusType.NORMAL.key);
        //获取sku属性
        JSONArray skuArray = JSONArray.parseArray(JSON.toJSONString(skuMapList));
        Map<String, ShopSkuAttribute> skuAttributeMap = new HashMap<>();
        EntityWrapper<ShopSkuAttribute> skuAttributeEntityWrapper;

        for (int i = 0; i < skuArray.size(); i++) {
            JSONObject skuJson = skuArray.getJSONObject(i);
            Integer skuId = skuJson.getInteger("id");
            //转换金额等数据
            skuAttributeEntityWrapper = new EntityWrapper<>();
            skuAttributeEntityWrapper.where("sku_id=" + skuId);
            List<ShopSkuAttribute> skuAttributeList = skuAttributeService.selectList(skuAttributeEntityWrapper);
            for (ShopSkuAttribute skuAttribute : skuAttributeList) {
                if (StringUtils.isNotBlank(skuAttribute.getImage())) {
                    skuAttributeMap.put(skuAttribute.getAttributeValue(), skuAttribute);
                }
            }
            skuJson.put("skuAttributeList", skuAttributeList);
        }
        List<ShopSkuAttribute> skuAttributes = new ArrayList<>();
        Set<Map.Entry<String, ShopSkuAttribute>> entry = skuAttributeMap.entrySet();
        Iterator<Map.Entry<String, ShopSkuAttribute>> iterator = entry.iterator();
        while (iterator.hasNext()) {
            skuAttributes.add(iterator.next().getValue());
        }
        String skuImageAttributeList = JSON.toJSONString(skuAttributes);
        //获取参数类型枚举
        JSONObject paramTypes = ParamType.getJsonArray();

        model.addAttribute("imageList", imageList);
        model.addAttribute("paramTypes", paramTypes);
        model.addAttribute("product", product);
        model.addAttribute("paramList", JSON.toJSONString(paramList));
        model.addAttribute("productParamList", JSON.toJSONString(productParamList));
        model.addAttribute("attributeKeyList", JSON.toJSONString(attributeKeyList));
        model.addAttribute("productAttributeList", JSON.toJSONString(productAttributeList));
        model.addAttribute("skuArray", skuArray);
        model.addAttribute("skuImageAttributeList", skuImageAttributeList);
        return "/manage/product/product/update.jsp";
    }

    @ApiOperation(value = "新增商品")
    @RequiresPermissions("product:product:update")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Object update(@RequestBody JSONObject param) {
        /**
         * param :
         * product 商品基本信息
         * skus sku数组，商品所包含的sku基本信息
         * hasAttribute boolean 是否包含属性
         * attributes 属性数组
         */
        JSONObject productJson = param.getJSONObject("product");
        ShopProduct product = productJson.toJavaObject(ShopProduct.class);
        JSONArray skusArray = param.getJSONArray("skus");
        List<ShopSku> skuList = skusArray.toJavaList(ShopSku.class);
        ComplexResult result = doValidator(product, skuList);
        if (null != result) {
            return new ShopResult(ShopResultConstant.FAILED, result.getErrors().get(0).getErrorMsg());
        }
        try {
            productService.updateProduct(param);
        } catch (ShopException e) {
            return new ShopResult(ShopResultConstant.FAILED, e.getMessage());
        }
        return new ShopResult(ShopResultConstant.SUCCESS, ShopResultConstant.SUCCESS);
    }

    @ApiOperation(value = "上下架商品")
    @RequiresPermissions("product:product:update")
    @RequestMapping(value = "/updateMarketable", method = RequestMethod.POST)
    @ResponseBody
    public Object updateMarketable(@RequestBody JSONObject param) {
        Integer productId = param.getInteger("productId");
        ShopProduct product = productService.selectById(productId);
        Boolean marketable = param.getBoolean("marketable");
        product.setMarketable(marketable);
        productService.updateById(product);
        return new ShopResult(ShopResultConstant.SUCCESS, ShopResultConstant.SUCCESS);
    }
}
